package es.xpt.ysf.commons.jaas;

import static javax.ejb.TransactionAttributeType.REQUIRED;

import java.util.List;
import java.util.TreeSet;

import javax.annotation.Resource;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;

import es.xpt.ysf.YSFException;
import es.xpt.ysf.dao.DAOException;
import es.xpt.ysf.jaas.YSFLoginModule;
import es.xpt.ysf.jaas.YSFPrincipal;
import es.xpt.ysf.model.Item;
import es.xpt.ysf.utils.UUID;


@Stateless(name = "JaasSession")
@TransactionAttribute(REQUIRED)
public class JaasSessionBean implements JaasSession{
	
	@Resource
	private SessionContext context;
	
	public JaasSessionBean() {
	}
	

	/* (non-Javadoc)
	 * @see es.xpt.ysf.commons.jaas.JaasSession#getEntityUsers(java.lang.String, java.lang.String)
	 */
	public List<YSFPrincipal> getEntityUsers(String entity, String entityId) 
			throws YSFException{
		
		if (entity == null || entity.trim().length()<=0)
			throw new NullPointerException("entity");
		
		JaasDAOFactory f = null;
		try {
			f = new JaasDAOFactory(context.getCallerPrincipal());
			UsersDAO dao = f.getUsersDAO();
			return dao.getEntityUsers(entityId, entity);
		} finally {
			if (f != null) f.release();
		}
	}
	

	/* (non-Javadoc)
	 * @see es.xpt.ysf.commons.jaas.JaasSession#getAllEntityUsers(java.lang.String)
	 */
	public List<YSFPrincipal> getAllEntityUsers(String entity) 
			throws YSFException{
		
		if (entity == null || entity.trim().length()<=0)
			throw new NullPointerException("entity");
		
		JaasDAOFactory f = null;
		try {
			f = new JaasDAOFactory(context.getCallerPrincipal());
			UsersDAO dao = f.getUsersDAO();
			return dao.getEntityUsers(null, entity);
		} finally {
			if (f != null) f.release();
		}
	}


	/* (non-Javadoc)
	 * @see es.xpt.ysf.commons.jaas.JaasSession#insertUser(es.xpt.ysf.jaas.YSFPrincipal, java.lang.String, java.lang.String, java.lang.String)
	 */
	public void insertUser(YSFPrincipal principal, String pass, List<Item> roles, String entityId, String entity) throws YSFException {
		if (entity == null || entity.trim().length()<=0)
			throw new NullPointerException("entity");
		
		if (entityId == null || entityId.trim().length()<=0)
			throw new NullPointerException("entityId");
		
		if (pass == null || pass.trim().length()<=0)
			throw new NullPointerException("pass");
		
		if (principal == null || principal.getName() == null || principal.getName().trim().length()<=0)
			throw new NullPointerException("principal");
		
	
		JaasDAOFactory f = null;
		try {
			f = new JaasDAOFactory(context.getCallerPrincipal());
			UsersDAO dao = f.getUsersDAO();
			principal.setCompany(((YSFPrincipal)context.getCallerPrincipal()).getCompany());
			dao.insert(principal, YSFLoginModule.encrypt(pass));
			dao.addUserEntity(entityId, entity, principal.getName());
			dao.addUserRoles(principal.getName(), roles);
			
		} catch (DAOException e) {
			context.setRollbackOnly();
			throw e;
		} finally {
			if (f != null) f.release();
		}
	}
	


	/* (non-Javadoc)
	 * @see es.xpt.ysf.commons.jaas.JaasSession#deleteUser(java.lang.String, java.lang.String, java.lang.String)
	 */
	public void deleteUser(String entityId, String entity, String principal) throws YSFException {
		if (entity == null || entity.trim().length()<=0)
			throw new NullPointerException("entity");
		
		if (entityId == null || entityId.trim().length()<=0)
			throw new NullPointerException("entityId");
		
		if (principal == null || principal.trim().length()<=0)
			throw new NullPointerException("principal");
		
		
		JaasDAOFactory f = null;
		try {
			f = new JaasDAOFactory(context.getCallerPrincipal());
			UsersDAO dao = f.getUsersDAO();
			dao.removeUserEntity(entityId, entity, principal);
			dao.removeUserRoles(principal);
			dao.delete(principal);
		} catch (DAOException e) {
			context.setRollbackOnly();
			throw e;
		} finally {
			if (f != null) f.release();
		}

	}

	/* (non-Javadoc)
	 * @see es.xpt.ysf.commons.jaas.JaasSession#updateUser(es.xpt.ysf.jaas.YSFPrincipal, boolean)
	 */
	public void updateUser(YSFPrincipal principal, String pass, List<Item> roles) throws YSFException {
		if (principal == null || principal.getName() == null || principal.getName().trim().length()<=0)
			throw new NullPointerException("principal");
		if ( pass!=null && pass.trim().length() <= 0 )
			throw new NullPointerException("pass");
		
		JaasDAOFactory f = null;
		try {
			f = new JaasDAOFactory(context.getCallerPrincipal());
			UsersDAO dao = f.getUsersDAO();
			dao.update(principal, pass!=null?YSFLoginModule.encrypt(pass):null);
			dao.removeUserRoles(principal.getName());
			dao.addUserRoles(principal.getName(), roles);
		} catch (DAOException e) {
			context.setRollbackOnly();
			throw e;
		} finally {
			if (f != null) f.release();
		}
	}

	// ROLES
	
	public List<Item> getRoles() throws YSFException {
		JaasDAOFactory f = null;
		try {
			f = new JaasDAOFactory(context.getCallerPrincipal());
			RolesDAO dao = f.getRolesDAO();
			return dao.getRoles();
		} finally {
			if (f != null) f.release();
		}
	}

	
	public TreeSet<String> getRolePrivileges(String role) throws YSFException {
		JaasDAOFactory f = null;
		try {
			f = new JaasDAOFactory(context.getCallerPrincipal());
			RolesDAO dao = f.getRolesDAO();
			return dao.getRolePrivileges(role);
		} finally {
			if (f != null) f.release();
		}
	}

	public void deleteRole(String role) throws YSFException {
		if ( role==null || role.trim().length() <= 0 )
			throw new NullPointerException("role");
		
		JaasDAOFactory f = null;
		try {
			f = new JaasDAOFactory(context.getCallerPrincipal());
			RolesDAO dao = f.getRolesDAO();
			dao.deleteRole(role);
		} catch (DAOException e) {
			context.setRollbackOnly();
			throw e;
		} finally {
			if (f != null) f.release();
		}
	}

	public void insertRole(Item role) throws YSFException {
		if ( role==null || role.getShortName() == null || role.getShortName().trim().length() <= 0 )
			throw new NullPointerException("shorName");
		
		JaasDAOFactory f = null;
		try {
			f = new JaasDAOFactory(context.getCallerPrincipal());
			RolesDAO dao = f.getRolesDAO();
			role.setCode(UUID.randomUUID());
			dao.insertRole(role);
		} finally {
			if (f != null) f.release();
		}
	}

	public void updateRole(Item role) throws YSFException {
		if ( role==null || role.getShortName() == null || role.getShortName().trim().length() <= 0 )
			throw new NullPointerException("shorName");
		
		if ( role.getCode() == null || role.getCode().trim().length() <= 0 )
			throw new NullPointerException("code");
		
		JaasDAOFactory f = null;
		try {
			f = new JaasDAOFactory(context.getCallerPrincipal());
			RolesDAO dao = f.getRolesDAO();
			dao.updateRole(role);
		} finally {
			if (f != null) f.release();
		}
	}
	
	public void removePrivilege(String role, String privilege)
			throws YSFException {
		
		if ( role==null || role.trim().length() <= 0 )
			throw new NullPointerException("role");
		
		if ( privilege==null || privilege.trim().length() <= 0 )
			throw new NullPointerException("privilege");
		
		JaasDAOFactory f = null;
		try {
			f = new JaasDAOFactory(context.getCallerPrincipal());
			RolesDAO dao = f.getRolesDAO();
			dao.removePrivilege(role, privilege);
		} finally {
			if (f != null) f.release();
		}
		
	}

	public void removePrivileges(String role, String[] privileges)
			throws YSFException {

		if ( role==null || role.trim().length() <= 0 )
			throw new NullPointerException("role");
		
		JaasDAOFactory f = null;
		try {
			f = new JaasDAOFactory(context.getCallerPrincipal());
			RolesDAO dao = f.getRolesDAO();
			dao.removePrivileges(role, privileges);
		} finally {
			if (f != null) f.release();
		}
	}

	public void insertPrivileges(String role, String[] privileges)
			throws YSFException {

		if ( role==null || role.trim().length() <= 0 )
			throw new NullPointerException("role");
		
		
		JaasDAOFactory f = null;
		try {
			f = new JaasDAOFactory(context.getCallerPrincipal());
			RolesDAO dao = f.getRolesDAO();
			dao.insertPrivileges(role, privileges);
		} finally {
			if (f != null) f.release();
		}
	}

	public void insertPrivilege(String role, String privilege)
			throws YSFException {
		if ( role==null || role.trim().length() <= 0 )
			throw new NullPointerException("role");
		
		if ( privilege==null || privilege.trim().length() <= 0 )
			throw new NullPointerException("privilege");
		
		JaasDAOFactory f = null;
		try {
			f = new JaasDAOFactory(context.getCallerPrincipal());
			RolesDAO dao = f.getRolesDAO();
			dao.insertPrivilege(role, privilege);
		} finally {
			if (f != null) f.release();
		}
	}


	public List<Item> getUserRoles(String principal, String credential) throws YSFException {
		if ( principal==null || principal.trim().length() <= 0 )
			throw new NullPointerException("principal");
		
		JaasDAOFactory f = null;
		try {
			f = new JaasDAOFactory(context.getCallerPrincipal());
			RolesDAO dao = f.getRolesDAO();
			return dao.getUserRoles(principal, credential);
		} finally {
			if (f != null) f.release();
		}
	}

/*	
	public List<String> getUserPrivileges(String principal)
			throws DAOException {
		String selectStatement = "SELECT DISTINCT privilege"
				+ " FROM ysf_jaas_role_privilege p, ysf_jaas_principal_role r"
				+ " WHERE p.role=r.role"
				+ " AND r.principal ='" + principal +  "' order by privilege";
		
		Statement stmt = null;
	    try {
	    	stmt = con.createStatement();
	    	ResultSet rs = stmt.executeQuery(selectStatement);
	    	ArrayList<String> al = new ArrayList<String>();
	    	while ( rs.next() ) {
	    		al.add(rs.getString("privilege"));
	    	}
	       return al;
	    } catch (SQLException se){
	      throw new DAOException(se);
	    } finally {
	    	if ( stmt!=null ) stmt.close();
	    }
	}


*/

}
